From: Rui Matos Date: Thu, 2 Apr 2015 22:18:07 +0000 (+0200) Subject: keyboard: Add a way to use the OSK on shell chrome in wayland sessions X-Git-Tag: archive/raspbian/50.5-1+rpi1~1^2~1013^2^2~1385 X-Git-Url: https://dgit.raspbian.org/%22http://www.example.com/cgi/%22/%22http:/www.example.com/cgi/%22?a=commitdiff_plain;h=5afd04781cbde9acf48bb9fa31b17d92050370f5;p=gnome-shell.git keyboard: Add a way to use the OSK on shell chrome in wayland sessions libcaribou was designed to generate X events which works under wayland sessions for X clients but obviously doesn't work for wayland clients and for shell chrome. This patch adds a simple caribou display adapter which inherits from its X display adapter and allows us to continue to work for X clients and at the same time makes the OSK work on shell text entries by sending key events directly to the focused text actor. Making the OSK work for wayland clients requires much bigger changes at various levels in the stack and either not using libcaribou or re-working it substantially so that's left for future work. https://bugzilla.gnome.org/show_bug.cgi?id=747274 --- diff --git a/js/ui/keyboard.js b/js/ui/keyboard.js index 393a179e8..20c45014b 100644 --- a/js/ui/keyboard.js +++ b/js/ui/keyboard.js @@ -184,6 +184,10 @@ const Keyboard = new Lang.Class({ this._daemonProxy = null; this._lastDeviceId = null; + if (Meta.is_wayland_compositor() && + Caribou.DisplayAdapter.set_default) + Caribou.DisplayAdapter.set_default(new ShellWaylandAdapter()); + Meta.get_backend().connect('last-device-changed', Lang.bind(this, function (backend, deviceId) { let manager = Clutter.DeviceManager.get_default(); @@ -725,3 +729,24 @@ const KeyboardSource = new Lang.Class({ this._keyboard.show(Main.layoutManager.bottomIndex); } }); + +const ShellWaylandAdapter = new Lang.Class({ + Name: 'ShellWaylandAdapter', + Extends: Caribou.XAdapter, + + vfunc_keyval_press: function(keyval) { + let focus = global.stage.get_key_focus(); + if (focus instanceof Clutter.Text) + Shell.util_text_insert_keyval(focus, keyval); + else + this.parent(keyval); + }, + + vfunc_keyval_release: function(keyval) { + let focus = global.stage.get_key_focus(); + if (focus instanceof Clutter.Text) + return; // do nothing + else + this.parent(keyval); + }, +}); diff --git a/src/shell-util.c b/src/shell-util.c index b0b90d614..ab8a0ce51 100644 --- a/src/shell-util.c +++ b/src/shell-util.c @@ -391,3 +391,15 @@ shell_util_need_background_refresh (void) return FALSE; } + +void +shell_util_text_insert_keyval (ClutterActor *actor, + guint keyval) +{ + ClutterEvent event = { 0 }; + + event.type = CLUTTER_KEY_PRESS; + event.key.keyval = keyval; + + clutter_actor_event (actor, &event, FALSE); +} diff --git a/src/shell-util.h b/src/shell-util.h index e7d3cc9fb..4474a0d6d 100644 --- a/src/shell-util.h +++ b/src/shell-util.h @@ -47,6 +47,9 @@ void shell_util_cursor_tracker_to_clutter (MetaCursorTracker *tracker, gboolean shell_util_need_background_refresh (void); +void shell_util_text_insert_keyval (ClutterActor *actor, + guint keyval); + G_END_DECLS #endif /* __SHELL_UTIL_H__ */